package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.server.game.commondata.maintask.*;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;


public class MainTaskBaseData {
    private static Logger logger = LoggerFactory.getLogger(MainTaskBaseData.class);

    private static ConcurrentHashMap<Integer, TaskType> taskTypeMap = new ConcurrentHashMap<>(); // 任务类型配置表

    private static ConcurrentHashMap<Integer, TaskDay> taskDayMap = new ConcurrentHashMap<>(); // 每日任务配置表
    private static ConcurrentHashMap<Integer, HonorReward> honorRewardMap = new ConcurrentHashMap<>(); // 荣誉奖励(全服或是个人)奖励配置表
    private static ConcurrentHashMap<Integer, TaskDay> maxTaskDayMap = new ConcurrentHashMap<>();// 日常任务最大值的配置另外存储，num配置最大的配置
    private static ConcurrentHashMap<Long, TaskAchieve> maxTaskAchieveMap = new ConcurrentHashMap<>();// 主线任务最大值的配置额外存储，num配置最大的配置
    private static ConcurrentHashMap<Integer, HonorReward> maxHonorRewardMap = new ConcurrentHashMap<>();// 荣誉奖励最大值的配置额外存储，num配置最大的配置

    private static ConcurrentHashMap<Integer, Integer> taskAchieveIdMap = new ConcurrentHashMap<>();// task_achieve表的id和task_type配置
    private static ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, TaskAchieve>> taskAchieveMap = new ConcurrentHashMap<>();// 主线任务和成就配置表

    // 公共数据初始化
    public static void init(List<Future> futures) {
        futures.add(initTaskAchieve());
        futures.add(initTaskType());
        futures.add(initTaskDay());
        futures.add(initHonorReward());
    }

    /**
     * 初始化主线任务和成就配置表
     */
    public static Future<Void> initTaskAchieve() {
        String table = "task_achieve";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, TaskAchieve>> tmp = new ConcurrentHashMap<>();
                    ConcurrentHashMap<Integer, Integer> tmp2 = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        TaskAchieve entity = new TaskAchieve(result.getJsonObject(i));
                        tmp.computeIfAbsent(entity.getTaskType(), k -> new ConcurrentHashMap<>()).put(entity.getId(), entity);
                        tmp2.put(entity.getId(), entity.getTaskType());
                        //tmp2.computeIfAbsent(entity.getTaskType(), k -> new HashSet<>()).add(entity.getParam());
                        long taskId = MainTaskManager.getTaskId(entity.getTaskType(), entity.getParam());
                        TaskAchieve taskAchieveMax = getMaxTaskAchieve(entity.getTaskType(), entity.getParam());
                        if (taskAchieveMax == null || entity.getNum() > taskAchieveMax.getNum()) {
                            maxTaskAchieveMap.put(taskId, entity);// 把num 最大的那条配置另外存储
                        }
                    }
                    taskAchieveMap = tmp;
                    taskAchieveIdMap = tmp2;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    // 根据id 获取task_achieve的配置
    public static TaskAchieve getTaskAchieve(int id) {
        int taskType = taskAchieveIdMap.containsKey(id) ? taskAchieveIdMap.get(id) : 0;
        ConcurrentHashMap<Integer, TaskAchieve> map = getTaskAchieveList(taskType);
        if (map == null) {
            return null;
        }
        return map.get(id);
    }

    // 获取num值最大的那条记录
    public static TaskAchieve getMaxTaskAchieve(int taskType, int param) {
        long taskId = MainTaskManager.getTaskId(taskType, param);
        TaskAchieve result = maxTaskAchieveMap.get(taskId);
        return result;
    }


    public static ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, TaskAchieve>> getTaskAchieveMap() { return taskAchieveMap; }

    // 获取某个task_type下的所有task_achieve配置, 没有时返回Null
    public static ConcurrentHashMap<Integer, TaskAchieve> getTaskAchieveList(int taskType) {
        ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, TaskAchieve>> map = getTaskAchieveMap();
        return map.get(taskType);
    }


    // 根据任务类型获取任务配置列表，过滤掉param重复的
    public static ConcurrentHashMap<Integer, TaskAchieve> getTaskAchieveMapByTaskType(int taskType) {
        ConcurrentHashMap<Integer, TaskAchieve> result = new ConcurrentHashMap<>();
        JsonArray jsonArray = new JsonArray();
        ConcurrentHashMap<Integer, TaskAchieve> map = getTaskAchieveList(taskType);
        if (map == null) {
            return result;
        }
        for (TaskAchieve taskAchieve : map.values()) {
            if (taskAchieve.getTaskType() == taskType && !Tool.isInList(jsonArray, taskAchieve.getParam())) {
                result.put(taskAchieve.getId(), taskAchieve);
                jsonArray.add(taskAchieve.getParam());
            }
        }
        return result;
    }

    /**
     * 初始化任务类型配置表
     */
    public static Future<Void> initTaskType() {
        String table = "task_type";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, TaskType> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        TaskType entity = new TaskType(result.getJsonObject(i));
                        tmp.put(entity.getTaskType(), entity);
                    }
                    taskTypeMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static TaskType getTaskType(int id) {
        TaskType result = taskTypeMap.get(id);
        if (result == null) {
            logger.error("getTaskType error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, TaskType> getTaskTypeMap() { return taskTypeMap; }


    // 获取num值最大的那条记录
    public static TaskDay getMaxTaskDayByTaskType(int taskType) {
        TaskDay result = maxTaskDayMap.get(taskType);
        return result;
    }

    /**
     * 初始化每日任务配置表
     */
    public static Future<Void> initTaskDay() {
        String table = "task_day";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, TaskDay> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        TaskDay entity = new TaskDay(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);

                        int taskType = entity.getTaskType();
                        TaskDay taskDayMax = getMaxTaskDayByTaskType(taskType);
                        if (taskDayMax == null || entity.getNum() > taskDayMax.getNum()) {
                            maxTaskDayMap.put(taskType, entity);// 把num 最大的那条配置另外存储
                        }
                    }
                    taskDayMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static TaskDay getTaskDay(int id) {
        TaskDay result = taskDayMap.get(id);
        if (result == null) {
            logger.error("getTaskDay error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, TaskDay> getTaskDayMap() { return taskDayMap; }

    /**
     * 初始化荣誉奖励(全服或是个人)奖励配置表
     */
    public static Future<Void> initHonorReward() {
        String table = "honor_reward";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + " order by num desc;";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, HonorReward> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        HonorReward entity = new HonorReward(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);

                        if (entity.getType() == MainTaskConstant.HONOR_TYPE_USER || entity.getType() == MainTaskConstant.HONOR_TYPE_UNION) {//  个人荣誉
                            int honorType = entity.getHonorType();
                            HonorReward honorRewardMax = getMaxHonorReward(honorType);
                            if (honorRewardMax == null || entity.getNum() > honorRewardMax.getNum()) {
                                maxHonorRewardMap.put(honorType, entity);// 把num 最大的那条配置另外存储
                            }
                        }
                    }
                    honorRewardMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static HonorReward getHonorReward(int id) {
        HonorReward result = honorRewardMap.get(id);
        if (result == null) {
            logger.error("getHonorReward error key = " + id);
        }
        return result;
    }
    public static HonorReward getHonorRewardByHonorType(int honorType) {
        for (HonorReward honorReward : getHonorRewardMap().values()) {
            if (honorReward.getHonorType() == honorType) {
                return honorReward;
            }
        }
        return null;
    }

    // 获取num值最大的那条记录
    public static HonorReward getMaxHonorReward(int honorType) {
        HonorReward result = maxHonorRewardMap.get(honorType);
        return result;
    }


    public static ConcurrentHashMap<Integer, HonorReward> getHonorRewardMap() { return honorRewardMap; }
}
